package com.unity.bh3.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.unity.bh3.dto.FriendMessageDTO;
import com.unity.bh3.dto.FriendRequestDTO;
import com.unity.bh3.dto.FriendListDTO;
import com.unity.bh3.mapper.FriendMessageMapper;
import com.unity.bh3.mapper.FriendRelationshipMapper;
import com.unity.bh3.mapper.UserStatusMapper;
import com.unity.bh3.model.FriendMessage;
import com.unity.bh3.model.FriendRelationship;
import com.unity.bh3.model.UserStatus;
import com.unity.bh3.netty.WebSocketMessage;
import com.unity.bh3.service.FriendService;
import com.unity.bh3.service.UserService;
import com.unity.bh3.dto.UserInfoResponse;
import com.unity.bh3.netty.WebSocketManager;
import com.unity.bh3.util.TimeUtil;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FriendServiceImpl implements FriendService {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private FriendRelationshipMapper friendRelationshipMapper;
    
    @Autowired
    private FriendMessageMapper friendMessageMapper;

    @Autowired
    private UserStatusMapper userStatusMapper;
    
    @Autowired
    private WebSocketManager webSocketManager;

    @Override
    public List<UserInfoResponse> searchUsers(String nickname, int limit) {
        return userService.searchUsersByNickname(nickname, limit);
    }

    @Override
    @Transactional
    public void sendFriendRequest(Long userId, Long friendId) {
        // 检查是否已经是好友
        LambdaQueryWrapper<FriendRelationship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRelationship::getUserId, userId)
                .eq(FriendRelationship::getFriendId, friendId);
        if (friendRelationshipMapper.selectCount(wrapper) > 0) {
           webSocketManager.sendErrorMessage(userId, "已发送过好友申请或已经是好友");
            throw new RuntimeException("已经发送过好友申请或已经是好友");
        }

        // 创建好友申请
        FriendRelationship relationship = new FriendRelationship();
        relationship.setUserId(userId);
        relationship.setFriendId(friendId);
        relationship.setStatus(0); // 待确认
        friendRelationshipMapper.insert(relationship);

        // 通过WebSocket通知对方
        webSocketManager.sendSystemMessage(userId, "已发送好友申请");
        webSocketManager.sendFriendRequest(friendId, userId);
    }

    @Override
    @Transactional
    public void handleFriendRequest(Long userId, Long friendId, boolean accept) {
        LambdaQueryWrapper<FriendRelationship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRelationship::getUserId, friendId)
                .eq(FriendRelationship::getFriendId, userId)
                .eq(FriendRelationship::getStatus, 0);
        
        FriendRelationship relationship = friendRelationshipMapper.selectOne(wrapper);
        if (relationship == null) {
            throw new RuntimeException("好友申请不存在或已处理");
        }

        relationship.setStatus(accept ? 1 : 2); // 1-已接受，2-已拒绝
        friendRelationshipMapper.updateById(relationship);

        if (accept) {
            // 创建双向好友关系
            FriendRelationship reverse = new FriendRelationship();
            reverse.setUserId(userId);
            reverse.setFriendId(friendId);
            reverse.setStatus(1);
            friendRelationshipMapper.insert(reverse);
        }
        webSocketManager.sendSystemMessage(userId, accept?"已接受好友申请":"已拒绝好友申请");
        // 通过WebSocket通知申请方处理结果
        webSocketManager.sendFriendRequestResult(friendId, userId, accept);
    }

    @Override
    public List<FriendListDTO> getFriendList(Long userId) {
        LambdaQueryWrapper<FriendRelationship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRelationship::getUserId, userId)
                .eq(FriendRelationship::getStatus, 1);
        
        List<FriendRelationship> relationships = friendRelationshipMapper.selectList(wrapper);
        List<Long> friendIds = relationships.stream()
                .map(FriendRelationship::getFriendId)
                .collect(Collectors.toList());

        return friendIds.stream()
                .map(friendId -> {
                    // 获取好友基本信息
                    UserInfoResponse userInfo = userService.getUserInfo(friendId);
                    
                    // 获取好友在线状态
                    UserStatus userStatus = userStatusMapper.selectById(friendId);
                    
                    // 查询未读消息数量
                    LambdaQueryWrapper<FriendMessage> messageWrapper = new LambdaQueryWrapper<>();
                    messageWrapper.eq(FriendMessage::getSenderId, friendId)
                            .eq(FriendMessage::getReceiverId, userId)
                            .eq(FriendMessage::getStatus, 0); // 未读状态
                    Long unreadCount = friendMessageMapper.selectCount(messageWrapper);
                    
                    return FriendListDTO.builder()
                            .id(userInfo.getId())
                            .username(userInfo.getUsername())
                            .nickname(userInfo.getNickname())
                            .email(userInfo.getEmail())
                            .level(userInfo.getLevel())
                            .exp(userInfo.getExp())
                            .stamina(userInfo.getStamina())
                            .crystals(userInfo.getCrystals())
                            .displayCharacterId(userInfo.getDisplayCharacterId())
                            .isOnline(userStatus != null && userStatus.getIsOnline())
                            .lastLoginTime(userStatus != null ? TimeUtil.formatRelativeTime(userStatus.getLastLoginTime()) : "未知")
                            .unreadMessageCount(unreadCount.intValue())
                            .createdTime(userInfo.getCreatedTime())
                            .updatedTime(userInfo.getUpdatedTime())
                            .build();
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<FriendRequestDTO> getFriendRequests(Long userId) {
        try {
            if (userId == null) {
                throw new RuntimeException("用户ID不能为空");
            }
            
            log.info("获取用户[{}]的好友申请列表", userId);
            
            // 获取好友申请列表
            LambdaQueryWrapper<FriendRelationship> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FriendRelationship::getFriendId, userId)
                    .eq(FriendRelationship::getStatus, 0)
                    .orderByDesc(FriendRelationship::getCreatedTime);
            
            List<FriendRelationship> requests = friendRelationshipMapper.selectList(wrapper);
            
            // 转换为DTO
            List<FriendRequestDTO> dtoList = requests.stream()
                    .map(request -> {
                        // 获取申请者信息
                        UserInfoResponse userInfo = userService.getUserInfo(request.getUserId());
                        // 获取申请者在线状态
                        UserStatus userStatus = userStatusMapper.selectById(request.getUserId());
                        
                        return FriendRequestDTO.builder()
                                .userId(request.getUserId())
                                .nickname(userInfo.getNickname())
                                .exp(userInfo.getExp())
                                .status(request.getStatus())
                                .isOnline(userStatus != null && userStatus.getIsOnline())
                                .build();
                    })
                    .collect(Collectors.toList());
            
            log.info("用户[{}]的好友申请列表数量: {}", userId, dtoList.size());
            
            return dtoList;
        } catch (RuntimeException e) {
            log.error("获取好友申请列表失败: userId={}, error={}", userId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("获取好友申请列表时发生未知错误: userId={}", userId, e);
            throw new RuntimeException("获取好友申请列表失败，请稍后重试");
        }
    }

    @Override
    public void sendMessage(Long senderId, Long receiverId, String content) {
        // 检查是否是好友
        LambdaQueryWrapper<FriendRelationship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRelationship::getUserId, senderId)
                .eq(FriendRelationship::getFriendId, receiverId)
                .eq(FriendRelationship::getStatus, 1);
        if (friendRelationshipMapper.selectCount(wrapper) == 0) {
            throw new RuntimeException("不是好友关系，无法发送消息");
        }

        // 保存消息
        FriendMessage message = new FriendMessage();
        message.setSenderId(senderId);
        message.setReceiverId(receiverId);
        message.setContent(content);
        message.setStatus(0); // 未读
        friendMessageMapper.insert(message);

        // 通过WebSocket推送消息
        webSocketManager.sendFriendMessage(receiverId, message);
    }

    @Override
    public List<FriendMessage> getUnreadMessages(Long userId) {
        LambdaQueryWrapper<FriendMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendMessage::getReceiverId, userId)
                .eq(FriendMessage::getStatus, 0);
        return friendMessageMapper.selectList(wrapper);
    }

    @Override
    public void markMessageAsRead(Long messageId) {
        FriendMessage message = new FriendMessage();
        message.setId(messageId);
        message.setStatus(1); // 已读
        friendMessageMapper.updateById(message);
    }

    @Override
    public void markAllMessagesAsRead(Long userId, Long friendId) {
        friendMessageMapper.markMessagesAsRead(userId, friendId);
    }

    @Override
    public UserStatus getFriendStatus(Long friendId) {
        return userStatusMapper.selectById(friendId);
    }

    @Override
    public List<FriendMessageDTO> getHistoryMessages(Long userId, Long friendId) {
        // 查询两个用户之间的所有历史消息
        List<FriendMessage> messages = friendMessageMapper.getHistoryMessages(userId, friendId);
        
        // 转换为DTO并添加发送者信息
        return messages.stream()
                .map(message -> {
                    // 获取发送者信息
                    UserInfoResponse senderInfo = userService.getUserInfo(message.getSenderId());
                    
                    return FriendMessageDTO.builder()
                            .id(message.getId())
                            .senderId(message.getSenderId())
                            .receiverId(message.getReceiverId())
                            .senderNickname(senderInfo.getNickname())
                            .senderLevel(senderInfo.getLevel())
                            .content(message.getContent())
                            .status(message.getStatus())
                            .createdTime(message.getCreatedTime())
                            .build();
                })
                .collect(Collectors.toList());
    }

    @Override
    public void updateUserStatus(Long userId, boolean isOnline) {
        UserStatus status = userStatusMapper.selectById(userId);
        if (status == null) {
            // 如果记录不存在，创建新记录
            status = new UserStatus();
            status.setUserId(userId);
            status.setIsOnline(isOnline);
            status.setLastLoginTime(isOnline ? LocalDateTime.now() : null);
            status.setUpdatedTime(LocalDateTime.now());
            userStatusMapper.insert(status);
        } else {
            // 更新现有记录
            status.setIsOnline(isOnline);
            if (isOnline) {
                status.setLastLoginTime(LocalDateTime.now());
            }
            status.setUpdatedTime(LocalDateTime.now());
            userStatusMapper.updateById(status);
        }

        // 通知该用户的所有好友状态变化
        LambdaQueryWrapper<FriendRelationship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRelationship::getFriendId, userId)
                .eq(FriendRelationship::getStatus, 1);
        List<FriendRelationship> friends = friendRelationshipMapper.selectList(wrapper);
        
        // 获取格式化的最后登录时间
        String formattedLastLoginTime = TimeUtil.formatRelativeTime(status.getLastLoginTime());
        
        for (FriendRelationship friend : friends) {
            webSocketManager.sendFriendStatusUpdate(friend.getUserId(), userId, isOnline, formattedLastLoginTime);
        }
    }
    
    @Override
    @Transactional
    public void deleteFriend(Long userId, Long friendId) {
        log.info("开始删除好友关系: userId={}, friendId={}", userId, friendId);
        
        if (userId == null || friendId == null) {
            throw new RuntimeException("用户ID和好友ID不能为空");
        }
        
        if (userId.equals(friendId)) {
            throw new RuntimeException("不能删除自己");
        }
        
        // 删除双向好友关系
        LambdaQueryWrapper<FriendRelationship> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(FriendRelationship::getUserId, userId)
                .eq(FriendRelationship::getFriendId, friendId)
                .eq(FriendRelationship::getStatus, 1); // 只删除已确认的好友关系
        
        LambdaQueryWrapper<FriendRelationship> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(FriendRelationship::getUserId, friendId)
                .eq(FriendRelationship::getFriendId, userId)
                .eq(FriendRelationship::getStatus, 1);
        
        int deleted1 = friendRelationshipMapper.delete(wrapper1);
        int deleted2 = friendRelationshipMapper.delete(wrapper2);
        
        if (deleted1 == 0 && deleted2 == 0) {
            throw new RuntimeException("好友关系不存在或已被删除");
        }
        
        log.info("删除好友关系成功: userId={}, friendId={}, deleted1={}, deleted2={}", 
                userId, friendId, deleted1, deleted2);
        
        // 通过WebSocket通知双方
        webSocketManager.sendSystemMessage(userId, "已删除好友");
        webSocketManager.sendSystemMessage(friendId, "好友已将您删除");
    }
}